package com.vladimirkolarevic.eventplanner.tapestry.services;

import com.vladimirkolarevic.eventplanner.hibernate.AttendServiceHibernate;
import com.vladimirkolarevic.eventplanner.hibernate.EventsServiceHibernate;
import com.vladimirkolarevic.eventplanner.hibernate.MembershipsServiceHibernate;
import com.vladimirkolarevic.eventplanner.service.AttendService;
import com.vladimirkolarevic.eventplanner.service.EventsService;
import com.vladimirkolarevic.eventplanner.service.MembershipsService;
import com.vladimirkolarevic.eventplanner.spring_hibernate.AttendanceDAO;
import com.vladimirkolarevic.eventplanner.spring_hibernate.EventDAO;
import com.vladimirkolarevic.eventplanner.spring_hibernate.MembershipDAO;

import org.apache.tapestry5.*;
import org.apache.tapestry5.hibernate.HibernateSymbols;
import org.apache.tapestry5.hibernate.HibernateTransactionAdvisor;
import org.apache.tapestry5.hibernate.HibernateTransactionDecorator;
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.MethodAdviceReceiver;

import org.apache.tapestry5.ioc.ServiceBinder;

import org.apache.tapestry5.ioc.annotations.Match;


/**
 * This module is automatically included as part of the Tapestry IoC Registry, it's a good place to
 * configure and extend Tapestry, or to place your own service definitions.
 */
public class AppModule
{
    public static void bind(ServiceBinder binder)
    {
       binder.bind(MembershipsService.class, MembershipDAO.class);
       binder.bind(EventsService.class, EventDAO.class);
       
       binder.bind(AttendService.class, AttendanceDAO.class);
        // binder.bind(MyServiceInterface.class, MyServiceImpl.class);
        
        // Make bind() calls on the binder object to define most IoC services.
        // Use service builder methods (example below) when the implementation
        // is provided inline, or requires more initialization than simply
        // invoking the constructor.
    }
    
    
    public static void contributeApplicationDefaults(
            MappedConfiguration<String, String> configuration)
    {
        // Contributions to ApplicationDefaults will override any contributions to
        // FactoryDefaults (with the same key). Here we're restricting the supported
        // locales to just "en" (English). As you add localised message catalogs and other assets,
        // you can extend this list of locales (it's a comma separated series of locale names;
        // the first locale name is the default when there's no reasonable match).
        
        configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");

        // The factory default is true but during the early stages of an application
        // overriding to false is a good idea. In addition, this is often overridden
        // on the command line as -Dtapestry.production-mode=false
        configuration.add(SymbolConstants.PRODUCTION_MODE, "false");

        // The application version number is incorprated into URLs for some
        // assets. Web browsers will cache assets because of the far future expires
        // header. If existing assets are changed, the version number should also
        // change, to force the browser to download new versions.
        configuration.add(SymbolConstants.APPLICATION_VERSION, "1.0-SNAPSHOT");
        configuration.add(HibernateSymbols.EARLY_START_UP, "true");
    }
    

    /**
     * This is a service definition, the service will be named "TimingFilter". The interface,
     * RequestFilter, is used within the RequestHandler service pipeline, which is built from the
     * RequestHandler service configuration. Tapestry IoC is responsible for passing in an
     * appropriate Logger instance. Requests for static resources are handled at a higher level, so
     * this filter will only be invoked for Tapestry related requests.
     * 
     * <p>
     * Service builder methods are useful when the implementation is inline as an inner class
     * (as here) or require some other kind of special initialization. In most cases,
     * use the static bind() method instead. 
     * 
     * <p>
     * If this method was named "build", then the service id would be taken from the 
     * service interface and would be "RequestFilter".  Since Tapestry already defines
     * a service named "RequestFilter" we use an explicit service id that we can reference
     * inside the contribution method.
     */    
 
    

    public static void contributeHibernateEntityPackageManager(
			Configuration<String> configuration) {
		configuration.add("com.vladimirkolarevic.eventplanner.beans");
	}


    @Match("*Service")
	public static <T> T decorateTransactionally(
			HibernateTransactionDecorator decorator, Class<T> serviceInterface,
			T delegate, String serviceId) {
		return decorator.build(serviceInterface, delegate, serviceId);
	}

   /* public static  Memberships buildMembership(){
        return new MembeshipsBean();
    }*/
    @Match("*Service")
    public static void adviseTransactions(HibernateTransactionAdvisor advisor, MethodAdviceReceiver receiver){
    	advisor.addTransactionCommitAdvice(receiver);
    }

}
